<?php

class AtomParser implements IRssParser
{
    const CUSTOM_NAMESPACE_PREFIX = "atom";

    protected $xPathHelper = null;

    public function __construct(DOMDocument $rssXmlObject)
    {
        $this->xPathHelper = new XPathHelper($rssXmlObject);
        $this->RegisterCustomNamespacePrefix();
    }

    public function GetMainNode()
    {
        $query = $this->AddCustomPrefix("/feed");
        return $this->xPathHelper->GetNode($query);
    }

    public function GetItemNodes()
    {
        $query = $this->AddCustomPrefix("/feed/entry");
        return $this->xPathHelper->GetNodes($query);
    }

    public function GetTitle($node)
    {
        return $this->GetTextByPrefixedQuery("title", $node);
    }

    public function GetDescription($node)
    {
        return $this->GetTextByPrefixedQuery("subtitle | summary", $node);
    }

    public function GetLink($node)
    {
        return $this->GetAttributeByPrefixedQuery("link/@href", $node);
    }

    public function GetDate($node)
    {
        return $this->GetTextByPrefixedQuery("updated", $node);
    }

    public function GetAuthor($node)
    {
        return $this->GetTextByPrefixedQuery("author/name | contributor/name", $node);
    }

    public function GetPostContent( $node )
    {
        $htmlContent = $this->GetPostHtmlContent($node);
        $postContentParser = new PostContentParser($htmlContent);
        return $postContentParser->GetPureContent();
    }

    public function GetPostImage($node, $sourceUrl)
    {
        $htmlContent = $this->GetPostHtmlContent($node);
        $postContentParser = new PostContentParser($htmlContent);
        return $postContentParser->GetPostImage($sourceUrl);
    }

    public function GetCategories( $node )
    {
        $categories = array();
        $query = $this->AddCustomPrefix("category");
        $categoryNodes = $this->xPathHelper->GetNodes($query, $node);
        foreach ( $categoryNodes as $categoryNode )
        {
            $categoryTitle = $this->GetAttributeByPrefixedQuery("@label | @term", $categoryNode);
            $rssCategory = new RssCategory();
            $rssCategory->SetTitle($categoryTitle);
            array_push($categories, $rssCategory);
        }
        return $categories;
    }

    private function GetPostHtmlContent( $node )
    {
        $contentNode = $this->GetContentNode($node);
        $htmlContent = "";
        if ( $contentNode != null )
        {
            $htmlContent = $contentNode->nodeValue;
            $htmlContent = ( !$this->IsContentTextual($contentNode) && !empty($htmlContent) ) ? $htmlContent : "";
        }
        return $htmlContent;
    }

    private function GetContentNode( $node )
    {
        $query = $this->AddCustomPrefix("content");
        return $this->xPathHelper->GetNode($query, $node);
    }

    private function IsContentTextual(DOMElement $contentNode)
    {
        return ($contentNode->getAttribute("type") == "text");
    }

    /** Registers custom namespace prefix with url defined in Atom document.
     *  This workaround is needed to enable XPath queries within Atom documents, otherwise they will return null.
     *
     */
    private function RegisterCustomNamespacePrefix()
    {
        $nsUri = $this->xPathHelper->GetNode(".")->lookupnamespaceURI(null);
        $this->xPathHelper->xpath->registerNamespace(self::CUSTOM_NAMESPACE_PREFIX, $nsUri);
    }

    /** Wrapper for XPathHelper::GetTextByPrefixedQuery method
    *   adds custom namespace prefix to queries
    */
    private function GetTextByPrefixedQuery( $expr, $node = null )
    {
        $expr = $this->AddCustomPrefix( $expr );
        $result = $this->xPathHelper->GetText( $expr, $node );
        return ( $result !== null ) ? $result : "";
    }

    /** Gets value of attribute of DOM element via query
     *
     */
    private function GetAttributeByPrefixedQuery( $expr, $node = null )
    {
        $expr = $this->AddCustomPrefix( $expr );
        $attrNode = $this->xPathHelper->GetNode( $expr, $node );
        return ( $attrNode ) ? $attrNode->value : "";
    }

    private function AddCustomPrefix( $query )
    {
        $query = preg_replace("/\/(\w+)/", "/" . self::CUSTOM_NAMESPACE_PREFIX . ":$1", $query);
        $query = preg_replace("/\|\s+(\w+)/", "| " . self::CUSTOM_NAMESPACE_PREFIX . ":$1", $query);
        return preg_replace("/^\w+/", self::CUSTOM_NAMESPACE_PREFIX . ":$0", $query);
    }
}

?>